package com.meisiabc.app.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.meisiabc.app.repository.db.entity.FreeAudition;
import com.meisiabc.app.repository.db.entity.Student;
import com.meisiabc.app.repository.db.entity.WechatMpSession;
import com.meisiabc.app.repository.db.manager.FreeAuditionManager;
import com.meisiabc.app.repository.db.manager.StudentManager;
import com.meisiabc.app.repository.db.manager.WechatMpSessionManager;
import com.meisiabc.support.wechat.WechatMpClient;
import com.meisiabc.support.wechat.fix.FixMpXmlMessages;
import com.meisiabc.utils.DateTimeUtil;
import com.riversoft.weixin.common.event.ClickEvent;
import com.riversoft.weixin.common.event.EventRequest;
import com.riversoft.weixin.common.event.EventType;
import com.riversoft.weixin.common.message.MsgType;
import com.riversoft.weixin.common.message.XmlMessageHeader;
import com.riversoft.weixin.common.message.xml.TextXmlMessage;
import com.riversoft.weixin.common.oauth2.AccessToken;
import com.riversoft.weixin.mp.MpWxClientFactory;
import com.riversoft.weixin.mp.message.MpXmlMessages;
import com.riversoft.weixin.mp.template.Data;
import com.riversoft.weixin.mp.user.Users;
import com.riversoft.weixin.mp.user.bean.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.meisiabc.app.support.StringPool.WECHAT_MP_RECOMMENDER;
import static com.meisiabc.app.support.StringPool.WECHAT_MP_SUBSCRIBE;

@Slf4j
@Service
public class WechatService {
    @Autowired
    private WechatMpClient wechatMpClient;
    @Autowired
    private WechatMpSessionManager wechatMpSessionManager;
    @Autowired
    private StudentManager studentManager;
    @Autowired
    private FreeAuditionManager freeAuditionManager;
    @Autowired
    private MediaService mediaService;

    public String wechatLoginPage() {
        return wechatMpClient.authenticationUrl("https://meisiabc.cn/app/wechat/mp/login", "snsapi_base");
    }

    public String wechatLogin(String code) {
        AccessToken accessToken = wechatMpClient.getAccessToken(code);
        return accessToken.getOpenId();
    }

    public boolean alreadyBind(String openid) {
        WechatMpSession wechatMpSession = wechatMpSessionManager.getOne(new QueryWrapper<WechatMpSession>().eq("openid", openid));
        return wechatMpSession != null;
    }

    public void smsLogin(String openid, String mobile, DateTime now) {
        Date dateNow = now.toDate();
        String headImgUrl = "";
        User user = wechatMpClient.getUsers(openid);
        if (user != null) {
            log.info("绑定用户微信账户信息：{}", JSONObject.toJSON(user));
            if (StringUtils.isNotBlank(user.getHeadImgUrl())) {
                headImgUrl = user.getHeadImgUrl();
            }
        } else {
            log.info("获取用户信息失败");
        }

        wechatMpSessionManager.save(WechatMpSession.builder().openid(openid).mobile(mobile).createTime(dateNow).updateTime(dateNow).headImgUrl(headImgUrl).build());
        try {
            Map<String, Data> messages = new HashMap<>();

            Data first = new Data();
            first.setValue("您好，您的信息已绑定成功！");
            messages.put("first", first);

            String name = "";
            Student student = studentManager.selectByMobile(mobile);
            if (student != null) {
                name = student.getEnName();
            } else {
                FreeAudition freeAudition = freeAuditionManager.selectLastOneByMobile(mobile);
                if (freeAudition != null) {
                    name = freeAudition.getEnName();
                }
            }

            Data keyword1 = new Data();
            keyword1.setValue(name);
            messages.put("keyword1", keyword1);

            Data keyword2 = new Data();
            keyword2.setValue(mobile);
            messages.put("keyword2", keyword2);

            Data keyword3 = new Data();
            keyword3.setValue(now.toString(DateTimeUtil.yyyyMMddHHmmss));
            messages.put("keyword3", keyword3);

            Data remark = new Data();
            remark.setValue("感谢您的使用！");
            messages.put("remark", remark);

            wechatMpClient.sendTemplateMsg(openid, "GKkFyPPZjhtgoHev2leHNDfCKYlCg6GTZHD1wpf9tao", messages);


        } catch (Exception e) {
            log.error("", e);
        }
    }

    public String dealMsg(String msg) {
        log.info("wechat mp msg: {}", msg);
        try {
            XmlMessageHeader xmlMessageHeader = FixMpXmlMessages.fromXml(msg);
            if (xmlMessageHeader.getMsgType() == MsgType.event) {
                if (xmlMessageHeader instanceof EventRequest) {
                    return dealEvent((EventRequest) xmlMessageHeader);
                }

                return "success";
            }
        } catch (Exception e) {
            log.error("", e);
        }

        return "success";
    }

    private String dealEvent(EventRequest eventRequest) {
        if (eventRequest.getEventType() == EventType.subscribe) {
            TextXmlMessage textXmlMessage = new TextXmlMessage();
            textXmlMessage.setFromUser(eventRequest.getToUser());
            textXmlMessage.setToUser(eventRequest.getFromUser());
            textXmlMessage.setContent(WECHAT_MP_SUBSCRIBE);
            String msgResponse = MpXmlMessages.toXml(textXmlMessage);
            return msgResponse;
        }

        if (eventRequest.getEventType() == EventType.unsubscribe) {
            wechatMpSessionManager.remove(new QueryWrapper<WechatMpSession>().eq("openid", eventRequest.getFromUser()));
            return "success";
        }

        if (eventRequest.getEventType() == EventType.CLICK) {
            return dealClickEvent((ClickEvent) eventRequest);
        }

        return "success";
    }

    private String dealClickEvent(ClickEvent clickEvent) {
        if ("recommender".equals(clickEvent.getEventKey())) {
            WechatMpSession wechatMpSession = wechatMpSessionManager.getOne(new QueryWrapper<WechatMpSession>().eq("openid", clickEvent.getFromUser()));
            if (wechatMpSession != null && StringUtils.isNotBlank(wechatMpSession.getMobile())) {
                mediaService.sendRecommenderImg(clickEvent, wechatMpSession.getMobile());
                TextXmlMessage textXmlMessage = new TextXmlMessage();
                textXmlMessage.setFromUser(clickEvent.getToUser());
                textXmlMessage.setToUser(clickEvent.getFromUser());
                textXmlMessage.setContent(String.format(WECHAT_MP_RECOMMENDER, wechatMpSession.getMobile()));
                String msgResponse = MpXmlMessages.toXml(textXmlMessage);
                return msgResponse;
            } else {
                TextXmlMessage textXmlMessage = new TextXmlMessage();
                textXmlMessage.setFromUser(clickEvent.getToUser());
                textXmlMessage.setToUser(clickEvent.getFromUser());
                textXmlMessage.setContent(WECHAT_MP_SUBSCRIBE);
                String msgResponse = MpXmlMessages.toXml(textXmlMessage);
                return msgResponse;
            }
        }

        return "success";
    }

    public void menuInit() {
        wechatMpClient.menuInit();
    }

    public void smsClassBegin(String openid,String name,String courseName,String length) {
        try {
            Map<String, Data> messages = new HashMap<>();

            Data userName = new Data();
            userName.setValue(name);
            messages.put("userName", userName);

            Data keyword1 = new Data();
            keyword1.setValue(courseName);
            messages.put("courseName", keyword1);

            Data keyword2 = new Data();
            keyword2.setValue(length);
            messages.put("date", keyword2);

            Data remark = new Data();
            remark.setValue("感谢您的使用！");
            messages.put("remark", remark);

            wechatMpClient.sendTemplateMsg(openid, "Pv-4Qz4p-bovUukG-5BnNZAgm-kuagDEOJxPElNG3dA", messages);
        } catch (Exception e) {
            log.error("", e);
        }
    }

    public void smsStudentLeave(String openid,String name,String courseName,String date) {
        try {
            Map<String, Data> messages = new HashMap<>();

            Data first = new Data();
            first.setValue("同学您好，您的请假申请已通过审核");
            messages.put("first", first);

            Data userName = new Data();
            userName.setValue(name);
            messages.put("keyword1", userName);

            Data leaveDate = new Data();
            leaveDate.setValue(date);
            messages.put("keyword2", leaveDate);

            Data keyword1 = new Data();
            keyword1.setValue(courseName);
            messages.put("keyword3", keyword1);

            Data remark = new Data();
            remark.setValue("感谢您的使用！");
            messages.put("remark", remark);

            wechatMpClient.sendTemplateMsg(openid, "-P3JqUQVj0ZC47Z9m1aoK3MCJcHJwTwrKqGk_sKwjF4", messages);
        } catch (Exception e) {
            log.error("", e);
        }
    }

    public void smsTeacherLeave(String openid, String studentName, String teacherName, String courseName, String date) {
        try {
            Map<String, Data> messages = new HashMap<>();

            Data first = new Data();
            first.setValue("尊敬的" + studentName + "同学，因老师请假，您的课程发生了变动");
            messages.put("first", first);

            Data keyword1 = new Data();
            keyword1.setValue(teacherName);
            messages.put("keyword1", keyword1);

            Data keyword2 = new Data();
            keyword2.setValue(courseName);
            messages.put("keyword2", keyword2);

            Data keyword3 = new Data();
            keyword3.setValue(date);
            messages.put("keyword3", keyword3);

            Data remark = new Data();
            remark.setValue("");
            messages.put("remark", remark);

            wechatMpClient.sendTemplateMsg(openid, "NO5onJCYj1x-22csSXQOTHdIDi2nGNOQFhH9Ke8XhEE", messages);
        } catch (Exception e) {
            log.error("", e);
        }
    }
}
